package com.yykj.common.util;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.utils.Jackson;
import com.tencent.cloud.CosStsClient;
import com.tencent.cloud.Response;
import com.yykj.common.config.ConfigUtil;
import com.yykj.common.dto.StsDTO;
import com.yykj.common.enums.ResultEnums;
import com.yykj.common.exception.NormalException;
import org.springframework.util.StringUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.TreeMap;

public class LocalUploadFile {
    public static String uploadFile(File file, String saveName) {
        LocalDate localDate = LocalDate.now();
        String dateStr = localDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        StsDTO sts = sts(dateStr);
        return upFileWithSTS(sts, saveName, file);
    }

    public static String uploadFile(File file) {
        String name = file.getName();
        String suffix = "";
        if (!StringUtils.isEmpty(name)) {
            suffix = name.substring(name.lastIndexOf("."));
        }
        return uploadFile(file, LocalStringUtil.getUUID() + suffix);
    }

    public static void main(String[] args) {
        String na = "aa.jpg";
        System.out.println(na.substring(na.lastIndexOf(".")));
    }


    /**
     * 上传文件
     *
     * @param sts          临时
     * @param saveFilename 保存名称
     * @param uploadFile   上传的文件
     */
    public static String upFileWithSTS(StsDTO sts, String saveFilename, File uploadFile) {
        // 用户基本信息
        String tmpSecretId = sts.getTmpSecretId();   // 替换为 STS 接口返回给您的临时 SecretId
        String tmpSecretKey = sts.getTmpSecretKey();
        // 替换为 STS 接口返回给您的临时 SecretKey
        String sessionToken = sts.getSessionToken();  // 替换为 STS 接口返回给您的临时 Token

        // 1 初始化用户身份信息(secretId, secretKey)
        COSCredentials cred = new BasicCOSCredentials(tmpSecretId, tmpSecretKey);
        // 2 设置 bucket 区域,详情请参阅 COS 地域 https://cloud.tencent.com/document/product/436/6224
        com.qcloud.cos.ClientConfig clientConfig = new com.qcloud.cos.ClientConfig(new Region(ConfigUtil.region));
        // 3 生成 cos 客户端
        COSClient cosclient = new COSClient(cred, clientConfig);
        // bucket 名需包含 appid
        // yykj-1307182424
        String key = sts.getUploadPath() + saveFilename;
        // 上传 object, 建议 20M 以下的文件使用该接口
        PutObjectRequest putObjectRequest = new PutObjectRequest(ConfigUtil.bucketName, key, uploadFile);

        // 设置 x-cos-security-token header 字段
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setSecurityToken(sessionToken);
        putObjectRequest.setMetadata(objectMetadata);

        try {
            PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
            // 成功：putobjectResult 会返回文件的 etag
            String etag = putObjectResult.getETag();
        } catch (Exception e) {
            e.printStackTrace();
            throw new NormalException(ResultEnums.UPLOAD_ERROR, ResultEnums.UPLOAD_ERROR.getMessage() + e.getMessage());
        }
        // 关闭客户端
        cosclient.shutdown();
        return ConfigUtil.domain + key;
    }

    public static StsDTO sts(String dateStr) {

        TreeMap<String, Object> config = new TreeMap<String, Object>();
        try {
            // 替换为您的 SecretId
            config.put("SecretId", ConfigUtil.secretId);
            // 替换为您的 SecretKey
            config.put("SecretKey", ConfigUtil.secretKey);

            // 临时密钥有效时长，单位是秒，默认1800秒，目前主账号最长2小时（即7200秒），子账号最长36小时（即129600秒）
            config.put("durationSeconds", 1800);

            // 换成您的 bucket
            config.put("bucket", ConfigUtil.bucketName);
            // 换成 bucket 所在地区
            config.put("region", ConfigUtil.region);

            String uploadPath = ConfigUtil.prefix + dateStr + "/";
            // 这里改成允许的路径前缀，可以根据自己网站的用户登录态判断允许上传的具体路径，例子：a.jpg 或者 a/* 或者 * 。
            // 如果填写了“*”，将允许用户访问所有资源；除非业务需要，否则请按照最小权限原则授予用户相应的访问权限范围。
            config.put("allowPrefixes", new String[]{
                    uploadPath + "*"
            });

            // 密钥的权限列表。必须在这里指定本次临时密钥所需要的权限。
            // 简单上传、表单上传和分片上传需要以下的权限，其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
            String[] allowActions = new String[]{
                    // 简单上传
                    "name/cos:PutObject",
                    // 表单上传、小程序上传
                    "name/cos:PostObject",
                    // 分块上传
                    "name/cos:InitiateMultipartUpload",
                    "name/cos:ListMultipartUploads",
                    "name/cos:ListParts",
                    "name/cos:UploadPart",
                    "name/cos:CompleteMultipartUpload"
            };
            config.put("allowActions", allowActions);

            Response response = CosStsClient.getCredential(config);
            //成功返回临时密钥信息，如下打印密钥信息
            System.out.println(Jackson.toJsonPrettyString(response));

            StsDTO dto = StsDTO.convert(response);
            dto.setUploadPath(uploadPath);
            dto.setRegion(ConfigUtil.region);
            dto.setBucketName(ConfigUtil.bucketName);

            System.out.println(Jackson.toJsonPrettyString(dto));
            return dto;
        } catch (Exception e) {
            e.printStackTrace();
            throw new IllegalArgumentException("no valid secret !");
        }
    }

    public static void downLoadRemoteFile(String remoteFilePath, String localFilePath) {
        URL urlfile = null;
        HttpURLConnection httpUrl = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        File f = new File(localFilePath);
        try {
            urlfile = new URL(remoteFilePath);
            httpUrl = (HttpURLConnection) urlfile.openConnection();
            httpUrl.connect();
            bis = new BufferedInputStream(httpUrl.getInputStream());
            bos = new BufferedOutputStream(new FileOutputStream(f));
            int len = 2048;
            byte[] b = new byte[len];
            while ((len = bis.read(b)) != -1) {
                bos.write(b, 0, len);
            }
            bos.flush();
            bis.close();
            httpUrl.disconnect();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                bis.close();
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}
